<template>
  <div>
    <el-form-item :prop="item.name || ''" :label="item.label" v-bind="item.formItemProps || {}" ref="el-form-item">
      <el-select ref="input" v-model="mvalue" @change="onChange" v-bind="opt">
        <el-option v-for="option in options" :key="option.value" :label="option.label" :value="option.value"></el-option>
      </el-select>
    </el-form-item>
  </div>
</template>

<script>
  import { objectAssign } from "../../utils/common";
  import Required from "../validMixins/Required";

  /**
   *
      item 特殊属性说明：

      // 做级联下拉框时的总数据表
      source: [],
      // 存放子类所使用的属性（里面必须是个数组）
      childrenAttr: "children",
      // 存放 value 键名，默认值：value
      valueAttr: "",
      // 存放 label 的键名，默认值：label
      labelAttr: "",


      做级联下拉的思路：

      由一级下拉框保存数据，当一级下拉框修改（包括初始化时），筛选出当前选项下的子类数据，通过
      notify通知下级下拉框。
      下级下拉框在接到数据后，重置自身的options，并根据当前的mvalue，筛选它的下级下拉框，再用
      notify来通知。
      如此循环往复。
   */
  export default {
    name: "PopoSelect",
    props: {
      value: [String, Array, Number],
      item: { type: Object },
      formData: { type: Object },
    },
    mixins: [Required],
    data() {
      return {
        mvalue: this.value,
        opt: {},
        // 做级联下拉框时，当前级别的父级的ID集合。
        parent_id_list: [],
        options: [],
      };
    },
    created() {
      // console.log( "select complete");
      this.opt = objectAssign(
        {
          source: this.item.source || [],
          childrenAttr: this.item.childrenAttr || "children",
          valueAttr: this.item.valueAttr || "value",
          labelAttr: this.item.labelAttr || "label",
          labelToValue: this.item.labelToValue !== undefined ? this.item.labelToValue : false,
        },
        this.item.props
      );

      // this.item.source = this.item.source || [];
      // this.item.childrenAttr = this.item.childrenAttr || "children";
      // this.item.valueAttr = this.item.valueAttr || "value";
      // this.item.labelAttr = this.item.labelAttr || "label";

      // 因为 select 有一个province 的继承关系，这里做个延时
      this.$nextTick(() => {
        this.initOptions();
        this.emitLevelSelect();
      });
    },
    watch: {
      mvalue(val) {
        this.$emit("input", val);
        this.emitLevelSelect();
      },
    },
    methods: {
      onChange() {},
      initOptions() {
        var options = this.item.options || [];
        if (!!this.item.source && this.item.source.length) {
          options = this.washSource(this.item.source);
        }
        // 数组索引与源数组解绑
        options = options.slice(0);

        // 设置 defaultOption = null，则可不默认显示一个“全部”的选项。
        // 或者修改 defaultOption = "请选择"，也可以修改默认的“全部”选项的Label值。
        if (this.item.defaultOption !== null) {
          this.item.defaultOption = !!this.item.defaultOption ? this.item.defaultOption : "全部";
          options.unshift({ label: this.item.defaultOption, value: "" });
        }
        this.options = options;
      },
      washSource(source) {
        var opts = [];
        var labelAttr = this.item.labelAttr;
        var valueAttr = this.item.valueAttr;

        if (this.item.labelToValue) {
          valueAttr = labelAttr;
        }
        source.forEach((item) => {
          opts.push({
            label: item[labelAttr] + "",
            value: item[valueAttr] + "",
          });
        });

        return opts;
      },
      emitLevelSelect() {
        // 触发下级级联下拉框的改变
        if (!this.item.subSelectName) return;
        var children = [];
        var valueAttr = this.item.labelToValue ? this.item.labelAttr : this.item.valueAttr;

        var node = (this.item.source || []).find((item) => {
          return item[valueAttr] == this.mvalue;
        });

        if (!!node) {
          children = node[this.item.childrenAttr] || [];
        }

        this.$emit("notifyOtherComponent", this.item.subSelectName, this.mvalue, children);
      },
      // 接收到了消息
      handlerNotify() {
        // var args = Array.slice.call( null, arguments, 0);
        var args = Array.from(arguments);
        // console.log( "select handlerNotify",  args);
        if (args.length <= 1) return;

        var parent_id = args[0];
        var nodes = args[1];
        this.item.source = nodes;
        this.initOptions();
        this.emitLevelSelect();

        // 如果 options 里面没有 mvalue 的值，则将 mvalue清空
        var mvalue_found = this.options.some((item) => {
          return item.value == this.mvalue;
        });
        if (!mvalue_found) {
          this.mvalue = "";
        }
      },
    },
  };
</script>
<style scoped lang="scss">
::v-deep {
  .el-select {
    display: block;
  }
}
</style>

